/**
 * 
 */
package defi4;

import ihm.ChoixDuFichier;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import Utils.Fichier;
import chiffrement.IChiffrement;
import donnees.Variables;
import enigma.Enigma;

/**
 * @author Logan
 *
 */
public class Dechiffrement4 implements IChiffrement {

	private ChoixDuFichier c;
	private String contenu;
	private List<String> listeEnigma;
	private Empreinte empreintePrefixe;
	private Enigma machine;

	public Dechiffrement4() {
		c = new ChoixDuFichier(this);
		listeEnigma = new ArrayList<String>();
		empreintePrefixe = new Empreinte();
		machine = new Enigma();
	}

	@Override
	public void lancer() {
		long tempsDebut = System.currentTimeMillis();
		Fichier f = new Fichier(c.getFichier());
		contenu = f.getContenu();



		List<String>listePrefixe = decouperString(contenu);
		Empreinte empreintePrefixe = calculerEmpreinte(listePrefixe);
		System.out.println("=========== EMPREINTE DU FICHIER PREFIXES ================");
		System.out.println(empreintePrefixe);




		System.out.println("\n\n============ Enigma ==============");
		enigmaEmpreinte(empreintePrefixe);

		long tempsFin = System.currentTimeMillis();
		Float seconds = (tempsFin - tempsDebut) / 1000F;
		System.out.println("\n calcul effectue en : " + seconds.toString() + " secondes");
	}

	public CycleLettre calculerCycles(Alphabet a) {
		CycleLettre cl = new CycleLettre();
		int tmp = 0;

		for(int i = 0; i<a.listCc.size(); i++) {
			CoupleChar cc =a.listCc.get(i);
			//Si on est pas encore passé sur ce char.
			tmp = 0;
			if(!cc.ok) {
				Character firstChar = cc.char1;
				Character tmpChar = cc.char1;
				do {
					tmp++;
					a.setTrue(tmpChar);
					tmpChar = a.getChar2(tmpChar);
				}while(!firstChar.equals(tmpChar));
				cl.cycles.add(tmp);
			}
		}
		cl.trier();
		return cl;
	}

	/**
	 * Permet de decouper une string en une liste de string de taille 6.
	 * 
	 * @param s La chaine de caractere a decouper.
	 * @return La liste de String de taille 6.
	 */
	private List<String> decouperString(String s) {
		List<String> listS = new ArrayList<String>();
		while(s.length() > 0) {
			if(s.length() < 6) {
				s = "";
			}
			else {
				listS.add(s.substring(0, 6));
				s = s.substring(6, s.length() - 1);
			}
		}

		return listS;
	}

	private Alphabet construireAlphabet(Alphabet a, List<String> prefixes) {

		for(String s : prefixes) {
			CoupleChar cc = new CoupleChar(s.charAt(a.firstChar), s.charAt(a.secondChar));
			if(!a.listCc.contains(cc)) {
				a.add(cc);
			}
		}

		return a;

	}

	public Empreinte calculerEmpreinte(List<String> prefixes) {
		Empreinte res = new Empreinte();

		Alphabet a1 = new Alphabet(0, 3);
		Alphabet a2 = new Alphabet(1, 4);
		Alphabet a3 = new Alphabet(2, 5);


		a1 = construireAlphabet(a1, prefixes);
		a2 = construireAlphabet(a2, prefixes);
		a3 = construireAlphabet(a3, prefixes);

		a1.trier();
		a2.trier();
		a3.trier();

		res.cycles.add(calculerCycles(a1));
		res.cycles.add(calculerCycles(a2));
		res.cycles.add(calculerCycles(a3));

		return res;

	}

	public void enigmaEmpreinte(Empreinte prefixes){
		String alphabet = Variables.majuscule;
		int pos0 = 0, pos1 = 1, pos2 = 2;
		int test = 0;
		//Les changements de rotors 
		for(int rotor=0; rotor<6; rotor++){

			if(rotor == 1) {
				machine.switchRotors(1, 2);
				pos1 = 2;
				pos2 = 1;
			} else if(rotor == 2) {
				machine.switchRotors(0, 1);
				pos0 = 2;
				pos1 = 0;
			} else if(rotor == 3) {
				machine.switchRotors(0, 2);
				pos0 = 1;
				pos2 = 2;
			} else if(rotor == 4) {
				machine.switchRotors(1, 2);
				pos1 = 2;
				pos2 = 0;
			} else if(rotor == 5) {
				machine.switchRotors(0, 1);
				pos0 = 2;
				pos1 = 1;
			}

			for(int k=0; k<alphabet.length(); k++){
				for(int j=0; j<alphabet.length(); j++){
					for(int i=0; i<alphabet.length(); i++){

						//Parcours de l'alphabet
						for(int carac=0; carac<alphabet.length(); carac++){
							//initialisation des rotors
							machine.cleDuJour(i, j, k);
							//cle
							String cle = "";
							for(int c=0; c<6; c++){
								cle += machine.chiffrerMessage( Enigma.toLetter(carac) );
							}
							listeEnigma.add(cle);
							machine.reset();
						}

						test++;

						Empreinte emp = new Empreinte();
						emp = calculerEmpreinte(listeEnigma);

						if(emp.equals(prefixes)) {
							System.out.println("Empreinte n : " + test);
							System.out.println("Position des rotors : " + pos0 + " " + pos1 + " " + pos2);
							System.out.println("Cle du jour : " + i + " " + j + " " + k);
							System.out.println("");
						}

						listeEnigma.clear();
					}
				}
			}

		}
	}
}
